package com.woniuxy.pxxt.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.pxxt.common.enums.UserTrainStatus;
import com.woniuxy.pxxt.common.result.Result;
import com.woniuxy.pxxt.common.vo.exam.AnswerArrayElementVo;
import com.woniuxy.pxxt.common.vo.exam.ExamAnswerVo;
import com.woniuxy.pxxt.common.vo.test.TestVo;
import com.woniuxy.pxxt.dao.OptionDao;
import com.woniuxy.pxxt.dao.TestDao;
import com.woniuxy.pxxt.dao.UserScoreDao;
import com.woniuxy.pxxt.dao.UserTestDao;
import com.woniuxy.pxxt.dto.exam.ExamDto;
import com.woniuxy.pxxt.dto.SelectMenuDto;
import com.woniuxy.pxxt.entity.Test;
import com.woniuxy.pxxt.entity.User;
import com.woniuxy.pxxt.service.TestService;
import com.woniuxy.pxxt.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 考试的题目(Test)表服务实现类
 *
 * @author makejava
 * @since 2022-03-07 16:28:53
 */
@Service
public class TestServiceImpl implements TestService {
    //单选题数量
    private static final int SINGLE_QUESTION_NUM = 10;
    //多选题数量
    private static final int MULTIPLE_QUESTION_NUM = 10;

    @Autowired(required = false)
    private TestDao testDao;

    @Autowired(required = false)
    private OptionDao optionDao;

    @Autowired
    private UserScoreDao userScoreDao;

    @Autowired
    private UserTestDao userTestDao;

    @Override
    public Result addTest(TestVo test) {

       //
        //  testDao.addTest(test);


        return Result.ok();


    }

    @Override
    public Result deleteById(Integer id) {
        testDao.deleteById(id);
        return Result.ok();
    }


    @Override
    public Result findTest(Integer currentPage, Integer pageSize, Test test) {

        PageHelper.startPage(currentPage, pageSize);
        List<Test> testList = testDao.findTest(test);
        PageInfo<Test> pageInfo = PageInfo.of(testList);
        return Result.ok(pageInfo);
    }


    @Override
    public Result findTestScore(Integer userId, Integer trainId) {
        //获得对的试题数量 然后获得分数
        Double goodsTestNum = testDao.findTestScore(userId, trainId);
        if (goodsTestNum == null) {
            return Result.ok(0.0);
        }
        double v = new BigDecimal(goodsTestNum).divide(
                        new BigDecimal(20), 4, BigDecimal.ROUND_DOWN).
                multiply(new BigDecimal(100)).
                doubleValue();

        return Result.ok(v);
    }

    @Transactional
    @Override
    public Result findExamByTrainId(Integer trainId) {
        //查询出单选题目
        List<ExamDto> singleQuestion = getRandom(testDao.findSingleQuestion(trainId), SINGLE_QUESTION_NUM, trainId);
        //查询出多选题目
        List<ExamDto> multipleQuestion = getRandom(testDao.findMultipleQuestion(trainId), MULTIPLE_QUESTION_NUM, trainId);

        if (singleQuestion.size() < SINGLE_QUESTION_NUM || multipleQuestion.size() < MULTIPLE_QUESTION_NUM) {
            return Result.fail().message("题库数据不够，请联系管理员添加！");
        }
        singleQuestion.addAll(multipleQuestion);
        //排序
        for (int i = 0; i < singleQuestion.size(); i++) {
            singleQuestion.get(i).setSort(i + 1);
        }
        userTestDao.addExamDetils(singleQuestion);

        return Result.ok(singleQuestion);
    }


    //抽取试题
    private List<ExamDto> getRandom(List<ExamDto> questionList, int n, Integer trainId) {
        User user = TokenUtil.getUser();
        Integer userTrainId = userScoreDao.findUserTrainId(user.getId(), trainId);
        List backList = null;
        backList = new ArrayList<ExamDto>();
        Random random = new Random();
        int backSum = 0;
        if (questionList.size() >= n) {
            backSum = n;
        } else {
            backSum = questionList.size();
        }
        for (int i = 1; i <= backSum; i++) {
//       随机数的范围为0-list.size()-1
            int target = random.nextInt(questionList.size());
            ExamDto examDto = questionList.get(target);
            examDto.setUserTrainId(userTrainId);
            backList.add(examDto);
            questionList.remove(target);
        }
        return backList;
    }

    @Override
    public Result findBothStatus() {
        List<SelectMenuDto> difficultyStatus = testDao.findDifficultyStatus();
        List<SelectMenuDto> isMultilyStatus = testDao.findMultilyStatus();
        Object[] selectedOptions = new Object[2];
        selectedOptions[0] = difficultyStatus;
        selectedOptions[1] = isMultilyStatus;

        return Result.ok(selectedOptions);
    }


    @Transactional
    @Override
    public Result examMark(ExamAnswerVo examAnswer) {
        List<AnswerArrayElementVo> answerArray = examAnswer.getAnswerArray();
        userTestDao.updateAnswer(answerArray);
        List<AnswerArrayElementVo> radioAnswer = new ArrayList<>();
        List<AnswerArrayElementVo> multiChoiceAnswer = new ArrayList<>();
        for (int i = 0; i < answerArray.size(); i++) {
            AnswerArrayElementVo answerArrayElementVo = answerArray.get(i);
            if (answerArrayElementVo.getIsMultilychoice() == 2) {
                radioAnswer.add(answerArrayElementVo);
            } else {
                multiChoiceAnswer.add(answerArrayElementVo);
            }
        }
        Integer userId = TokenUtil.getUser().getId();
        if ((radioScore(radioAnswer) + multiChoiceScore(multiChoiceAnswer)) > 60) {
            userScoreDao.updateExamStatus(userId, examAnswer.getTrainId(), UserTrainStatus.getStatusInteger("通过考试"));
            return Result.ok("恭喜通过测试！已合格！");
        } else {
            userScoreDao.updateExamStatus(userId, examAnswer.getTrainId(), UserTrainStatus.getStatusInteger("考试失败"));
            return Result.fail("成绩不合格");
        }
    }

    private int radioScore(List<AnswerArrayElementVo> radioAnswer) {
        if (radioAnswer == null || radioAnswer.size() == 0) {
            return 0;
        }
        List<String> radioAnswerData = testDao.findAnswer(radioAnswer);
        //记录正确的题目数量
        int count = 0;
        for (int i = 0; i < radioAnswerData.size(); i++) {
            if (radioAnswerData.get(i).equals(radioAnswer.get(i).getAnswerId())) {
                count++;
            }
        }
        return count *= 4;
    }

    private int multiChoiceScore(List<AnswerArrayElementVo> radioAnswer) {
        if (radioAnswer == null || radioAnswer.size() == 0) {
            return 0;
        }
        List<String> multiChoiceAnswerData = testDao.findAnswer(radioAnswer);
        //记录正确的题目数量
        int count = 0;
        for (int i = 0; i < multiChoiceAnswerData.size(); i++) {
            String[] multiChoiceAnswer = multiChoiceAnswerData.get(i).split(",");
            String[] userMultiChoiceAnswer = radioAnswer.get(i).getAnswerId().split(",");
            Arrays.sort(userMultiChoiceAnswer);
            Arrays.sort(multiChoiceAnswer);
            if (multiChoiceAnswer.length == userMultiChoiceAnswer.length && Arrays.equals(multiChoiceAnswer, userMultiChoiceAnswer)) {
                count++;
            }
        }
        return count *= 6;
    }
}
